#ifndef _LINUX_FLASH_DEV_H
#define _LINUX_FLASH_DEV_H

#include <linux/types.h>
#include "drv_pcie.h"
#include "drv_pcie_irq.h"
#include "drv_cdev.h"

struct flash_data_t {
    u32 addr;
    u32 *data;
    u32 size;
};

/* IOCTL 命令定义 */
#define IOCTL_FLASH_MAGIC       'P'                                                 /* 标识设备驱动 */
#define IOCTL_FLASH_READ        _IORW(IOCTL_FLASH_MAGIC, 1, struct flash_data_t)    /* 从地址读取数据 */
#define IOCTL_FLASH_WRITE       _IOW(IOCTL_FLASH_MAGIC, 2, struct flash_data_t)     /* 向地址写入数据 */

/* 设备 */
struct flash_dev_t {
    void *parent;           /* 父设备指针 */
    struct device *dev;     /* 设备描述符 */
    struct mutex lock;      /* 互斥锁 */
    char name[32];          /* 设备名称 */
    u8 index;               /* 索引号 */

    u32 start_addr;         /* 起始地址 */
    u32 end_addr;           /* 结束地址 */
};

/* 控制器 */
struct flash_ctrl_t {
    struct device *dev;                                             /* 设备描述符 */
    struct mutex lock;                                              /* 互斥锁 */
    char name[32];                                                  /* 设备名称 */
    u8 num;                                                         /* 设备数量 */

    struct pcie_dev_t *ppdev;                                       /* PCIe 设备指针 */
    int (*read)(struct pcie_dev_t *ppdev, u32 addr);                /* 从地址读取数据 */
    int (*write)(struct pcie_dev_t *ppdev, u32 addr, u32 *data);    /* 向地址写入数据 */
    struct cdev_ctrl_t cdev_ctrl;                                   /* 字符设备控制器 */
    struct flash_dev_t *flash;                                      /* FLASH */

    u32 start_addr;                                                 /* 起始地址 */
    u32 end_addr;                                                   /* 结束地址 */
};

/* 初始化 FLASH 控制器 */
int init_flash_ctrl(struct pcie_dev_t *ppdev, struct cdev_dev_t *pcdev, 
                    struct flash_ctrl_t *pctrl, struct flash_dev_t *pdev, 
                    const char *ctrl_name, u8 dev_num);
/* 注销 FLASH 控制器 */
void exit_flash_ctrl(struct flash_ctrl_t *pctrl, u8 dev_num);

#endif /* _LINUX_FLASH_DEV_H */
